package drds.plus.executor.command_handler.query.join;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.command_handler.query.AbstractQueryHandler;
import drds.plus.executor.command_handler.query.IndexMatchType;
import drds.plus.executor.cursor.cursor.ISortingCursor;
import drds.plus.executor.data_node_executor.DataNodeExecutorContext;
import drds.plus.executor.repository.Repository;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlan;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Join;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Query;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;

@Slf4j
public class SortMergeJoinHandler extends AbstractQueryHandler {
    public Logger log() {
        return log;
    }

    public SortMergeJoinHandler() {
        super();
    }

    protected ISortingCursor doQuery(ExecuteContext executeContext, ExecutePlan executePlan, ISortingCursor cursor) throws RuntimeException {
        Repository repository = executeContext.getRepository();
        Join join = (Join) executePlan;
        final Query leftNode = join.getLeftNode();
        final Query rightNode = join.getRightNode();
        //
        ISortingCursor leftSideCursor = null;
        ISortingCursor rightSideCursor = null;
        int leftSideIndexMatch = -1;
        int rightSideIndexMatch = -1;
        //
        leftSideCursor = DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().execute(executeContext, leftNode);
        //如果左右一个节点join 列和该节点的order by列排序相同
        leftSideIndexMatch = getIndexMatchType(leftSideCursor.getOrderByList(), getOrderByList(join.getLeftJoinColumnList()));
        if (leftSideIndexMatch == IndexMatchType.not_match) {
            leftSideCursor = repository.getCursorFactory().temporaryTableSortCursor(executeContext, leftSideCursor, getOrderByList(join.getLeftJoinColumnList()), true, executePlan.getRequestId());
            leftSideIndexMatch = IndexMatchType.match;
        }
        //
        rightSideCursor = DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().execute(executeContext, rightNode);
        rightSideIndexMatch = getIndexMatchType(rightSideCursor.getOrderByList(), getOrderByList(join.getRightJoinColumnList()));
        if (rightSideIndexMatch == IndexMatchType.not_match) {
            rightSideCursor = repository.getCursorFactory().temporaryTableSortCursor(executeContext, rightSideCursor, getOrderByList(join.getRightJoinColumnList()), true, executePlan.getRequestId());
            rightSideIndexMatch = IndexMatchType.match;
        }
        //
        cursor = repository.getCursorFactory().sortMergeJoinCursor(executeContext, join, leftSideCursor, join.getLeftJoinColumnList(), rightSideCursor, join.getRightJoinColumnList());
        return cursor;
    }

}
